package com.company;

import java.awt.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;

/**
 * Created by Administrator on 2016.7.27.
 */
public class Trie {

    //树的入口
    private Tree tree;

    //带地址构造方法
    public Trie(String address) throws FileNotFoundException {
        tree=new Tree(address);
    }

    //内部类，其核心数据结构.
    private class Tree{
        //经过该节点的流量
        private int number=0;
        //该节点所标记的符号
        private String str=null;
        //是否是最后一个节点
        private boolean isEnd;
        //访问兄弟的指针
        private Tree brotherTree=null;
        //访问儿子的指针
        private Tree sonTree=null;
        //这个节点所储存的词语
        private String[] getWords;
        //最后一个节点的类型标记
        private String sign;

        //Tree的一个无参构造方法:
        private Tree(){

        }

        //Tree的给定地址构造方法:
        private Tree(String address) throws FileNotFoundException {
            number=0;
            isEnd =false;

            Scanner input=new Scanner(new File(address),"utf-8");

            while (input.hasNext()){
                String line=input.nextLine();
                ArrayList arrayList=Line.dispose(line);
                this.read(arrayList);
            }
        }

        //Tree的直接构造方法:
        private Tree(String str,boolean isEnd){
            this.str=str;
            this.isEnd = isEnd;
        }

        //获取该节点的流量
        private int getNumber(){
            return number;
        }

        //获取该节点的所标记的符号
        private String getStr(){
            return str;
        }

        //判断是否是最后一个节点
        private boolean isEnd(){
            return isEnd;
        }

        private void setSignt(String sign){
            this.sign=sign;
        }

        private void setGetWords(String getWords[]){
            this.getWords = getWords;
        }

        //获取sign标记
        private String getSign(){
            return sign;
        }

        //给出处理过的数据集合，给Tree读入这个集合
        private void read(ArrayList arrayList){
            String str=((String)arrayList.get(0));

            Tree point=this;

            for (int z=0,i=0,j=1;z<5;z++){

                if (point.getStr()==null){
                    point.str=str.substring(i,j);
                    point.number++;
                }else {
                    while (true) {
                        if (point.getStr().equals(str.substring(i, j))) {
                            point.number++;
                            break;
                        }else if (point.brotherTree == null) {
                            point.brotherTree = new Tree(str.substring(i, j), false);
                            point = point.brotherTree;
                            break;
                        }else {
                            point = point.brotherTree;
                        }
                    }
                }

                switch (z){
                    case 0: i++;j++;break;
                    case 1:i++;j=j+2;break;
                    case 2:i=i+2;j++;break;
                    case 3:i++;j=j+2;break;
                    case 4:{
                        point.setSignt(str.substring(7,8));
                        point.getWords =new String[arrayList.size()-1];
                        point.isEnd=true;
                        for (int k=1;k<arrayList.size();k++){
                            point.getWords[k-1]=(String)arrayList.get(k);
                        }
                    }
                }

                if (point.sonTree ==null){
                    point.sonTree =new Tree();
                }
                point=point.sonTree;
            }

        }
    }

    //给出任意一个编号，输出流经该编号的流量
    public int getFlow(String coding){
        Tree point=this.getPoint(coding);
        if (point==null){
            return -1;
        }else {
            return point.getNumber();
        }
    }

    //给出任意一个编号，输入该编号下的节点数
    public int getNodeNumber(String coding){
        Tree point=this.getPoint(coding);
        int nodeNumber=0;

        point=point.sonTree;
        while (point!=null){
            point=point.brotherTree;
            nodeNumber++;
        }

        return nodeNumber;
    }

    //给出任意一个编号，返回该编号所对应的那颗树的入口指针
    private Tree getPoint(String coding){
        ArrayList strings=new ArrayList();

        for (int i=0,j=0,k=1;k<=coding.length()&&i<5;i++){
            strings.add(coding.substring(j,k));

            switch (i){
                case 0: j++;k++;break;
                case 1:j++;k=k+2;break;
                case 2:j=j+2;k++;break;
                case 3:j++;k=k+2;break;
            }
        }

        Tree point=this.tree;
        for (int i=0;i<strings.size();i++){
            int z=0;

            while (point!=null){
                if(point.getStr().equals((String)strings.get(i))){
                    z=1;
                    break;
                }
                point=point.brotherTree;
            }

            if (z==0){
                System.out.println("不存在该序列");
                return null;
            }else {
                if(i!=strings.size()-1){
                    point=point.sonTree;
                }
            }
        }
        return point;
    }

    //给出任意一个编号，返回这个编号的所有词
    public String[] getWords(String coding){

        return getPoint(coding).getWords;
    }
}